using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using LeisureCenter.Api;

namespace LeisureCenter.Core
{
    class CommandsManager : ICommandsManager
    {
        public CommandsManager()
        {
            Application.Idle += new EventHandler(Application_Idle);
        }

        void Application_Idle(object sender, EventArgs e)
        {
            ExecuteQueuedCommands();
        }

        private Queue<LeisureCenterCommand> commands = new Queue<LeisureCenterCommand>();

        private void ExecuteQueuedCommands()
        {
            LeisureCenterCommand command;
            lock (commands)
            {
                if (commands.Count > 0)
                    command = commands.Dequeue();
                else
                    return;
            }
            ExecuteCommand(command);
        }

        private static void HideCursor()
        {
            Rectangle bounds = Screen.FromControl(Program.LeisureCenterInstance.MainForm).Bounds;
            Cursor.Position = new Point(bounds.Right, bounds.Bottom);
        }

        private static void ExecuteCommand(LeisureCenterCommand command)
        {
            Program.LeisureCenterInstance.MainForm.StartIdle();
            IPlaylistItem activePlaylistitem = Program.LeisureCenterInstance.PlaylistManager.Playlist.ActivePlaylistItemOrStub;
            if (Program.LeisureCenterInstance.MainForm.Visible && !activePlaylistitem.FullScreen)
                Program.LeisureCenterInstance.MainForm.FocusActiveList();
            switch (command)
            {
                case LeisureCenterCommand.Up:
                    if (!activePlaylistitem.FullScreen)
                        SendKeys.Send(@"{UP}");
                    else
                    {
                        if (!activePlaylistitem.HandleKey(Keys.Up))
                        {
                            activePlaylistitem.BigStepForward();
                            Program.LeisureCenterInstance.OsdForm.ShowOsd("", 3);
                        }
                    }
                    break;
                case LeisureCenterCommand.Down:
                    if (!activePlaylistitem.FullScreen)
                        SendKeys.Send(@"{DOWN}");
                    else
                    {
                        if (!activePlaylistitem.HandleKey(Keys.Down))
                        {
                            activePlaylistitem.BigStepBackward();
                            Program.LeisureCenterInstance.OsdForm.ShowOsd("", 3);
                        }
                    }
                    break;
                case LeisureCenterCommand.Left:
                    if (!activePlaylistitem.FullScreen)
                        SendKeys.Send(@"{LEFT}");
                    else
                    {
                        if (!activePlaylistitem.HandleKey(Keys.Left))
                        {
                            activePlaylistitem.StepBackward();
                            Program.LeisureCenterInstance.OsdForm.ShowOsd("", 3);
                        }
                    }
                    break;
                case LeisureCenterCommand.Right:
                    if (!activePlaylistitem.FullScreen)
                        SendKeys.Send(@"{RIGHT}");
                    else
                    {
                        if (!activePlaylistitem.HandleKey(Keys.Right))
                        {
                            activePlaylistitem.StepForward();
                            Program.LeisureCenterInstance.OsdForm.ShowOsd("", 3);
                        }
                    }
                    break;
                case LeisureCenterCommand.PageUp:
                    SendKeys.Send(@"{PGUP}");
                    break;
                case LeisureCenterCommand.PageDown:
                    SendKeys.Send(@"{PGDN}");
                    break;
                case LeisureCenterCommand.Select:
                    if (activePlaylistitem.FullScreen)
                        activePlaylistitem.HandleKey(Keys.Return);
                    else
                        Program.LeisureCenterInstance.MainForm.MainSelect();
                    break;
                case LeisureCenterCommand.AlternateSelect:
                    if (Form.ActiveForm == Program.LeisureCenterInstance.MainForm)
                        Program.LeisureCenterInstance.MainForm.AlternateSelect();
                    break;
                case LeisureCenterCommand.Play:
                    activePlaylistitem.Play();
                    break;
                case LeisureCenterCommand.Pause:
                    activePlaylistitem.Pause();
                    break;
                case LeisureCenterCommand.PlayPause:
                    activePlaylistitem.PlayPause();
                    break;
                case LeisureCenterCommand.StopEject:
                case LeisureCenterCommand.Stop:
                    Program.LeisureCenterInstance.PlaylistManager.Stop();
                    break;
                case LeisureCenterCommand.Previous:
                    Program.LeisureCenterInstance.PlaylistManager.Playlist.Previous();
                    break;
                case LeisureCenterCommand.Next:
                    Program.LeisureCenterInstance.PlaylistManager.Playlist.Next();
                    break;
                case LeisureCenterCommand.FastRewind:
                    activePlaylistitem.FastReverse();
                    break;
                case LeisureCenterCommand.FastForward:
                    activePlaylistitem.FastForward();
                    break;
                case LeisureCenterCommand.ShowHide:
                    Program.LeisureCenterInstance.MainForm.Visible = !Program.LeisureCenterInstance.MainForm.Visible;
                    if (Program.LeisureCenterInstance.MainForm.Visible)
                    {
                        Program.LeisureCenterInstance.MainForm.Activate();
                        Program.LeisureCenterInstance.MainForm.FocusActiveList();
                        HideCursor();
                    }
                    else
                        if (activePlaylistitem.FullScreen)
                        {
                            activePlaylistitem.FullScreen = false;
                            if (!activePlaylistitem.FullScreen)
                                Program.LeisureCenterInstance.OsdForm.Hide();
                        }
                    break;
                case LeisureCenterCommand.Exit:
                    Program.LeisureCenterInstance.MainForm.Close();
                    break;
                case LeisureCenterCommand.ToggleRandomMode:
                    Program.LeisureCenterInstance.playListManager.PlayMode ^= PlayMode.Random;
                    break;
                case LeisureCenterCommand.ToggleRepeatMode:
                    Program.LeisureCenterInstance.playListManager.PlayMode ^= PlayMode.Repeat;
                    break;
                case LeisureCenterCommand.ToggleFullScreen:
                    activePlaylistitem.FullScreen = !activePlaylistitem.FullScreen;
                    if (!activePlaylistitem.FullScreen)
                        Program.LeisureCenterInstance.OsdForm.Hide();
                    else
                        Program.LeisureCenterInstance.OsdForm.ShowAfterFullScreen();
                    HideCursor();
                    break;
                case LeisureCenterCommand.Back:
                    Program.LeisureCenterInstance.MainForm.BrowseToParent();
                    break;
                case LeisureCenterCommand.Refresh:
                    Program.LeisureCenterInstance.MainForm.RefreshFolder();
                    break;
                case LeisureCenterCommand.Update:
                    Program.LeisureCenterInstance.RequestUpdate();
                    break;
                case LeisureCenterCommand.OptionsSelect:
                    if (Program.LeisureCenterInstance.MainForm.Visible)
                        Program.LeisureCenterInstance.MainForm.OptionsSelect();
                    break;
                case LeisureCenterCommand.ShowOsd:
                    Program.LeisureCenterInstance.OsdForm.ShowAfterFullScreen();
                    break;
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        private const int WM_USER = 0x0400;

        private delegate void MethodDelegate();

        private void WakeUpMainForm()
        {
            PostMessage(Program.LeisureCenterInstance.MainForm.Handle, WM_USER, 0, 0);
        }

        #region ICommandsManager Membres

        public void EnqueueCommand(LeisureCenterCommand command)
        {
            lock (commands)
            {
                commands.Enqueue(command);
            }

            if (Program.LeisureCenterInstance.MainForm.InvokeRequired)
            {
                Program.LeisureCenterInstance.MainForm.Invoke(new MethodDelegate(WakeUpMainForm));
            }
            else
            {
                WakeUpMainForm();
            }
        }

        #endregion
    }
}
